package com.zhy.m.permission;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.bundle.IBundleManager;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by namee on 2015. 11. 17..
 * <br/>
 * modified by hongyangOhos 2016.02.21
 */
public class MPermissions {
    private static final String SUFFIX = "$$PermissionProxy";

    public static void requestPermissions(Ability object, int requestCode, String... permissions) {
        _requestPermissions(object, requestCode, permissions);
    }

    public static void requestPermissions(AbilitySlice object,
                                          int requestCode,
                                          String... permissions) {
        _requestPermissions(object, requestCode, permissions);
    }

    public static boolean shouldShowRequestPermissionRationale(AbilitySlice abilitySlice,
                                                               String permission,
                                                               int requestCode) {
        PermissionProxy proxy = findPermissionProxy(abilitySlice);
        if (!proxy.needShowRationale(requestCode)) {
            return false;
        }
        if (abilitySlice.verifySelfPermission(permission) == IBundleManager.PERMISSION_GRANTED) {
            proxy.rationale(abilitySlice, requestCode);
            return true;
        }
        return false;
    }

    private static void _requestPermissions(Object object, int requestCode, String... permissions) {

        List<String> deniedPermissions =
                Utils.findDeniedPermissions(Utils.getAbility(object), permissions);

        if (deniedPermissions.size() > 0) {
            if (object instanceof Ability) {
                ((Ability) object).requestPermissionsFromUser(
                        deniedPermissions.toArray(new String[deniedPermissions.size()]),
                        requestCode);
            } else if (object instanceof AbilitySlice) {
                ((AbilitySlice) object).requestPermissionsFromUser(
                        deniedPermissions.toArray(new String[deniedPermissions.size()]),
                        requestCode);
            } else {
                throw new IllegalArgumentException(
                        object.getClass().getName() + " is not supported!");
            }
        } else {
            doExecuteSuccess(object, requestCode);
        }
    }


    private static PermissionProxy findPermissionProxy(Object ability) {
        try {
            Class clazz = ability.getClass();
            Class injectorClazz = Class.forName(clazz.getName() + SUFFIX);
            return (PermissionProxy) injectorClazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        throw new RuntimeException(String.format(
                "can not find %s ," + " something when compiler.",
                ability.getClass().getSimpleName() + SUFFIX));
    }


    private static void doExecuteSuccess(Object ability, int requestCode) {
        findPermissionProxy(ability).grant(ability, requestCode);

    }

    private static void doExecuteFail(Object ability, int requestCode) {
        findPermissionProxy(ability).denied(ability, requestCode);
    }

    public static void onRequestPermissionsResult(Ability ability,
                                                  int requestCode,
                                                  String[] permissions,
                                                  int[] grantResults) {
        requestResult(ability, requestCode, permissions, grantResults);
    }

    private static void requestResult(Object obj,
                                      int requestCode,
                                      String[] permissions,
                                      int[] grantResults) {
        List<String> deniedPermissions = new ArrayList<>();
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != IBundleManager.PERMISSION_GRANTED) {
                deniedPermissions.add(permissions[i]);
            }
            if (grantResults[i] != IBundleManager.PERMISSION_GRANTED) {
                deniedPermissions.add(permissions[i]);
            }
        }
        if (deniedPermissions.size() > 0) {
            doExecuteFail(obj, requestCode);
        } else {
            doExecuteSuccess(obj, requestCode);
        }
    }
}
